package com.aji.protein.controller;

import com.aji.allcommon.result.Result;
import com.aji.allcommon.service.FileStorageService;

import com.aji.allcommon.utills.MultipartFileUtill;
import com.aji.protein.domain.ProData;
import com.aji.protein.domain.Protein;
import com.aji.protein.domain.dto.ProteinDataDto;
import com.aji.protein.domain.dto.ProteinDataUpdateDto;
import com.aji.protein.domain.po.ProDataUpdateDto;
import com.aji.protein.domain.vo.ProteinDataVo;
import com.aji.protein.service.ProDataService;
import com.aji.protein.service.ProteinService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Api(tags = "蛋白质管理相关接口")
@RestController
@RequestMapping("/protein")
@RequiredArgsConstructor
public class ProteinController {
    private final ProteinService proteinService;
    private final ProDataService proDataService;
    private final FileStorageService fileStorageService;

    @ApiOperation("增加 需要忽略id")
    @PostMapping()
    @Transactional
    public Result save(ProteinDataDto entity) throws IOException {
//        合法检验
        if (entity.getTxtFileList().length != 3) {
            return Result.error("文件数量默认为3个");
        }
        //文件上传，获取url，入库
        //1.1上传图片获取url
        MultipartFile imgFile = entity.getImgFile();
        //写入临时文件用于处理
        File filetxt = File.createTempFile("temp", null);
        imgFile.transferTo(filetxt);
        //获取两种图片流
        FileInputStream imgFileInput = new FileInputStream(filetxt);
        FileInputStream simpJpgFile = MultipartFileUtill.multipartTifToJpgFileInputStream(filetxt);
        String originalFilename = imgFile.getOriginalFilename();
        String simpFileName = originalFilename.substring(0, originalFilename.length() - 4) + ".jpg";
        String accessSimpFileName = fileStorageService.uploadFile("img/jpg", simpFileName, simpJpgFile, "img/jpg");
        String imgurl = fileStorageService.uploadFile("img/tif", imgFile.getOriginalFilename(), imgFileInput, imgFile.getContentType());
        //1.2入库protein
        Protein protein = Protein.builder().name(entity.getName()).pic_url(imgurl).pic_simp_url(accessSimpFileName).build();
        proteinService.save(protein);
        //2.1获取入库id
        LambdaQueryWrapper<Protein> proteinLambdaQueryWrapper
                = new LambdaQueryWrapper<Protein>()
                .select()
                .eq(Protein::getPic_url, protein.getPic_url());
        Protein one = proteinService.getOne(proteinLambdaQueryWrapper);
        //2.2上传txt获取urllist,并且入库
        MultipartFile[] txtFileList = entity.getTxtFileList();
        List<ProData> proDataList = new ArrayList<>();
        for (MultipartFile txt : txtFileList
        ) {
            File filetxt1 = File.createTempFile("temp", null);
            txt.transferTo(filetxt1);
            FileInputStream txtInput = new FileInputStream(filetxt1);
            String txturl = fileStorageService.uploadFile("txt", txt.getOriginalFilename(), txtInput, txt.getContentType());
            ProData proData = ProData.builder().name(txt.getOriginalFilename()).txt_url(txturl).protein_id(one.getId()).build();
            proDataList.add(proData);
        }
        proDataService.saveBatch(proDataList);
        return Result.success();
    }

    @ApiOperation("删除")
    @DeleteMapping("/{ids}")
    @Transactional
    public Result delete(@PathVariable List<Long> ids) {//
        //1.txt
        LambdaQueryWrapper<ProData> proDataLambdaQueryWrapper
                = new LambdaQueryWrapper<ProData>()
                .in(ids != null, ProData::getProtein_id, ids);
        //删除文件
        List<ProData> proDataList = proDataService.list(proDataLambdaQueryWrapper);
        for (ProData p : proDataList
        ) {
            fileStorageService.delete(p.getTxt_url());
        }
        //删除数据库内容
        proDataService.remove(proDataLambdaQueryWrapper);
        //2.img删除
        List<Protein> proteinList = proteinService.listByIds(ids);
        for (Protein p : proteinList
        ) {
            fileStorageService.delete(p.getPic_url());
            fileStorageService.delete(p.getPic_simp_url());
        }
        proteinService.removeByIds(ids);
        return Result.success();
    }

    @ApiOperation("修改")
    @PutMapping()
    @Transactional
    public Result updateById(ProteinDataUpdateDto proteinDataUpdateDto) throws IOException {
        Long id = proteinDataUpdateDto.getId();

        //修改
        Protein protein = Protein.builder().id(id).build();
        if (proteinDataUpdateDto.getName() != null && !proteinDataUpdateDto.getName().isEmpty()) {
            protein.setName(proteinDataUpdateDto.getName());
        }
        if (proteinDataUpdateDto.getImgFile() != null) {
            //删除之前的图片
            String picUrl = proteinService.getById(id).getPic_url();
            fileStorageService.delete(picUrl);
            MultipartFile imgFile = proteinDataUpdateDto.getImgFile();
            File filetxt1 = File.createTempFile("temp", null);
            imgFile.transferTo(filetxt1);
            FileInputStream imgFileInput = new FileInputStream(filetxt1);
            FileInputStream simpJpgFile = MultipartFileUtill.multipartTifToJpgFileInputStream(filetxt1);
            String originalFilename = imgFile.getOriginalFilename();
            String simpFileName = originalFilename.substring(0, originalFilename.length() - 4) + ".jpg";
            String accessSimpFileName = fileStorageService.uploadFile("img/jpg", simpFileName, simpJpgFile, "img/jpg");
            String imgurl = fileStorageService.uploadFile("img", imgFile.getOriginalFilename(), imgFileInput, imgFile.getContentType());
            protein.setPic_url(imgurl);
            protein.setPic_simp_url(accessSimpFileName);
        }
        //更新
        proteinService.updateById(protein);
        List<ProDataUpdateDto> proDataUpdateDtoList = proteinDataUpdateDto.getProDataUpdateDtoList();
        for (ProDataUpdateDto p : proDataUpdateDtoList
        ) {//删除
            Long id1 = p.getId();
            ProData proData = ProData.builder().id(id1).build();
            ProData byId = proDataService.getById(id1);
            fileStorageService.delete(byId.getTxt_url());
            MultipartFile txtFile = p.getTxtFile();
            File filetxt1 = File.createTempFile("temp", null);
            txtFile.transferTo(filetxt1);
            FileInputStream txtInput = new FileInputStream(filetxt1);
            String txturl = fileStorageService.uploadFile("txt", txtFile.getOriginalFilename(), txtInput, txtFile.getContentType());
            proData.setTxt_url(txturl);
            proData.setProtein_id(byId.getProtein_id());
            proData.setName(txtFile.getOriginalFilename());
            //更新
            proDataService.updateById(proData);
        }
        return Result.success();
    }

    @ApiOperation("查询 根据id")
    @GetMapping("/{id}")
    public Result getById(@PathVariable Long id) {
        Protein protein = proteinService.getById(id);
        LambdaQueryWrapper<ProData> proDataLambdaQueryWrapper
                = new LambdaQueryWrapper<ProData>()
                .select()
                .eq(id != null, ProData::getProtein_id, id);
        List<ProData> proDataList = proDataService.list(proDataLambdaQueryWrapper);
        ProteinDataVo proteinDataVo = ProteinDataVo.builder().proDataList(proDataList).protein(protein).build();
        return Result.success(proteinDataVo);
    }

    @ApiOperation("查询 全部")
    @GetMapping("/list")
    public Result list() {
        List<Protein> proteinList = proteinService.list();
        List<ProteinDataVo> proteinDataVoList = new ArrayList<>();
        for (Protein p : proteinList
        ) {
            Long id = p.getId();
            LambdaQueryWrapper<ProData> proDataLambdaQueryWrapper
                    = new LambdaQueryWrapper<ProData>()
                    .select()
                    .eq(id != null, ProData::getProtein_id, id);
            List<ProData> proDataList = proDataService.list(proDataLambdaQueryWrapper);
            ProteinDataVo proteinDataVo = ProteinDataVo.builder().proDataList(proDataList).protein(p).build();
            proteinDataVoList.add(proteinDataVo);
        }
        return Result.success(proteinDataVoList);

    }

    @ApiOperation("条件分页查询")
    @GetMapping("/{page}/{pageSize}")
    public Result listByConditionAndPage(@PathVariable int page, @PathVariable int pageSize, String name) {
        //合法检验
        if (page < 1 || pageSize < 1) {
            return Result.error("分页参数异常");
        }
        //查protein表
        Page<Protein> proteinPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<Protein> proteinLambdaQueryWrapper =
                new LambdaQueryWrapper<Protein>()
                        .select()
                        .like(name != null, Protein::getName, name);
        IPage<Protein> pageProtein = proteinService.page(proteinPage, proteinLambdaQueryWrapper);
        List<Protein> recordsProtein = pageProtein.getRecords();
        List<ProteinDataVo> proteinDataVoList = new ArrayList<>();
        //查proData表
        for (Protein p : recordsProtein
        ) {
            LambdaQueryWrapper<ProData> proDataLambdaQueryWrapper =
                    new LambdaQueryWrapper<ProData>()
                            .select()
                            .eq(p.getId() != null, ProData::getProtein_id, p.getId());
            List<ProData> proDataList = proDataService.list(proDataLambdaQueryWrapper);
            ProteinDataVo proteinDataVo = ProteinDataVo.builder().protein(p).proDataList(proDataList).build();
            proteinDataVoList.add(proteinDataVo);
        }
        //构造返回数据
        IPage<ProteinDataVo> proteinDataVoIPage= new Page<>(page,pageSize);
        proteinDataVoIPage.setCurrent(pageProtein.getCurrent());
        proteinDataVoIPage.setRecords(proteinDataVoList);
        proteinDataVoIPage.setTotal(pageProtein.getTotal());
        return Result.success(proteinDataVoIPage);
    }

    @ApiOperation("获取数据总量")
    @GetMapping("/count")
    public Result count(){
        int count = Math.toIntExact(proteinService.count());
        return Result.success(count);
    }
}
